package com.aooci.ordercat.service.impl;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Serializable;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.SimpleDateFormat;
import java.util.Locale;

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.aooci.ordercat.dao.OrdercatDAO;
import com.aooci.ordercat.dao.OrderedItemDAO;
import com.aooci.ordercat.dao.RecetteDAO;
import com.aooci.ordercat.domain.Recette;
import com.aooci.ordercat.enums.OrderType;
import com.aooci.ordercat.enums.OrderedItemType;
import com.aooci.ordercat.service.PrintingService;
import com.aooci.ordercat.vo.OperatedOrderVo;
import com.aooci.ordercat.vo.OrderedItemVo;

@Service("printingService")  
@Transactional
public class TestPrintingServiceImpl implements PrintingService, Serializable {
	private static final long serialVersionUID = -1188186526551270448L;
	
	private FileWriter fileWriter;
	private static final int DEFAULT_PRINTER_LINE_WIDTH = 41;
	private static final String RECEIPT_FORMAT_1 = "%1$3d  %2$-18S  %3$7.2f  %4$7.2f";
	private static final String RECEIPT_FORMAT_2 = "                %1$15s %2$9.2f";
	private static final String RECEIPT_FORMAT_3 = "%1$4d     %2$9.2f  %3$9.2f   %4$9.2f";
	
	private String testPrintingOutputFile;
	public void setTestPrintingOutputFile(String testPrintingOutputFile) {
		this.testPrintingOutputFile = testPrintingOutputFile;
	}

	private OrdercatDAO ordercatDAO;
	public void setOrdercatDAO(OrdercatDAO ordercatDAO) {
		this.ordercatDAO = ordercatDAO;
	}
	
	private OrderedItemDAO orderedItemDAO;
	public void setOrderedItemDAO(OrderedItemDAO orderedItemDAO) {
		this.orderedItemDAO = orderedItemDAO;
	}
	
	private RecetteDAO recetteDAO;
	/**
	 * @param recetteDAO the recetteDAO to set
	 */
	public void setRecetteDAO(RecetteDAO recetteDAO) {
		this.recetteDAO = recetteDAO;
	}
	
	public void initialize() throws IOException{
		
		//fileWriter = new FileWriter(new File("mytextfile.txt"));

	}
	
	
	private void printSingleLine() throws IOException{
		for(int i=0;i<DEFAULT_PRINTER_LINE_WIDTH;i++){
			this.fileWriter.write("_");
		}
		this.fileWriter.write("\n");
	}
	
	private void printDoubleLine() throws IOException{
		for(int i=0;i<DEFAULT_PRINTER_LINE_WIDTH;i++){
			this.fileWriter.write("=");
		}
		this.fileWriter.write("\n");
	}
	
	@Async
	public void printToKitchen(OperatedOrderVo operatedOrderVo) {
		
		try {
			this.fileWriter = new FileWriter(new File(this.testPrintingOutputFile), true);
			SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy HH:MM");
			
			if(operatedOrderVo.getOrdercat().getPrintCount() > 0){
				this.fileWriter.write(">>>>>>>>>>>>> Modification <<<<<<<<<<<<<<");
			}else{
				this.printDoubleLine();
			}
			this.fileWriter.write("\n");
			this.fileWriter.write(operatedOrderVo.getOrdercat().getType() + "              " + dateFormat.format(operatedOrderVo.getOrdercat().getCreationTimestamp().getTime()));
			this.fileWriter.write("\n");
			if(OrderType.DINING_HALL.equals(operatedOrderVo.getOrdercat().getType())){
				this.fileWriter.write("Table:" + operatedOrderVo.getDiningTable().getLabel() + "          Client:" + operatedOrderVo.getDiningTable().getNofClient() + "\n");
			}else if(OrderType.TAKEAWAY.equals(operatedOrderVo.getOrdercat().getType())){
				this.fileWriter.write(dateFormat.format(operatedOrderVo.getTakeaway().getTakingTimestamp().getTime()) + "\n");
			}

			this.printSingleLine();
			//List<OrderedItemVo> orderedItems = new ArrayList<OrderedItemVo>();
			boolean switcher = false;
			for(int sortGroupId:this.orderedItemDAO.selectSortGroupByOrdercatId(operatedOrderVo.getOrdercat().getId())){
//				SortGroup sortGroup = this.sortGroupDAO.findById(sortGroupId);
//				if(sortGroup.isPrintKitchen()){
					for(OrderedItemVo orderedItemVo: this.orderedItemDAO.selectByOrdercatIdAndSortGroup(operatedOrderVo.getOrdercat().getId(), sortGroupId)){
						if(orderedItemVo.getItem().isPrintKitchen()){
							if(switcher){
								orderedItemVo.setFirst(true);
								this.printSingleLine();
								switcher = false;
							}
	
							if((operatedOrderVo.getOrdercat().getPrintCount() > 0) && (orderedItemVo.getModifiedQuantity() > 0)){
								this.fileWriter.write("[+"+orderedItemVo.getModifiedQuantity()+"] ");
							}else if((operatedOrderVo.getOrdercat().getPrintCount() > 0) && (orderedItemVo.getModifiedQuantity() < 0)){
								this.fileWriter.write("["+orderedItemVo.getModifiedQuantity()+"] ");
							}else if((orderedItemVo.getRemark() != null) && (!orderedItemVo.getRemark().isEmpty())){
								this.fileWriter.write("[*] ");
							}
							this.fileWriter.write(orderedItemVo.getQuantity() + " X " + orderedItemVo.getItem().getLabel());
							
							if((orderedItemVo.getRemark() != null) && (!orderedItemVo.getRemark().isEmpty())){
								this.fileWriter.write(" (" + orderedItemVo.getRemark()+")\n");
							}else{
								this.fileWriter.write("\n");
							}
						}
					}
					switcher = true;
				//}
				
			}
			this.printDoubleLine();
			
			operatedOrderVo.getOrdercat().setPrintCount(operatedOrderVo.getOrdercat().getPrintCount() + 1);
			this.ordercatDAO.save(operatedOrderVo.getOrdercat());
			this.orderedItemDAO.resetModifiedQuantityByOrdercatId(operatedOrderVo.getOrdercat().getId());
			operatedOrderVo.setHasAddingKitchenItems(this.orderedItemDAO.hasAddingKitchenItems(operatedOrderVo.getOrdercat().getId()));
			operatedOrderVo.setHasKitchenItems(this.orderedItemDAO.hasKitchenItems(operatedOrderVo.getOrdercat().getId()));
		
			this.fileWriter.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
	
	@Async
	public void printAddingToKitchen(OperatedOrderVo operatedOrderVo) {
		try {
			this.fileWriter = new FileWriter(new File(this.testPrintingOutputFile), true);
			SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy HH:MM");

			this.printDoubleLine();
			this.fileWriter.write(operatedOrderVo.getOrdercat().getType() + "              " + dateFormat.format(operatedOrderVo.getOrdercat().getCreationTimestamp().getTime()));
			this.fileWriter.write("\n");
			if(OrderType.DINING_HALL.equals(operatedOrderVo.getOrdercat().getType())){
				this.fileWriter.write("Table:" + operatedOrderVo.getDiningTable().getLabel() + "          Client:" + operatedOrderVo.getDiningTable().getNofClient() + "\n");
			}else if(OrderType.TAKEAWAY.equals(operatedOrderVo.getOrdercat().getType())){
				this.fileWriter.write(dateFormat.format(operatedOrderVo.getTakeaway().getTakingTimestamp().getTime()) + "\n");
			}

			this.printSingleLine();
			boolean switcher = false;
			for(int sortGroupId:this.orderedItemDAO.selectSortGroupByOrdercatId(operatedOrderVo.getOrdercat().getId())){
//				SortGroup sortGroup = this.sortGroupDAO.findById(sortGroupId);
//				if(sortGroup.isPrintKitchen()){
					for(OrderedItemVo orderedItemVo: this.orderedItemDAO.selectByOrdercatIdAndSortGroup(operatedOrderVo.getOrdercat().getId(), sortGroupId)){
						if(orderedItemVo.getItem().isPrintKitchen()){
							if(switcher){
								orderedItemVo.setFirst(true);
								this.printSingleLine();
								switcher = false;
							}
	
							if(orderedItemVo.getModifiedQuantity() > 0){
								this.fileWriter.write(orderedItemVo.getModifiedQuantity() + " X " + orderedItemVo.getItem().getLabel());
								
								if((orderedItemVo.getRemark() != null) && (!orderedItemVo.getRemark().isEmpty())){
									this.fileWriter.write(" (" + orderedItemVo.getRemark()+")\n");
								}else{
									this.fileWriter.write("\n");
								}
							}
						}	
					}
					switcher = true;
				//}
			}
			this.printDoubleLine();

			operatedOrderVo.getOrdercat().setPrintCount(operatedOrderVo.getOrdercat().getPrintCount() + 1);
			this.ordercatDAO.save(operatedOrderVo.getOrdercat());
			this.orderedItemDAO.resetModifiedQuantityByOrdercatId(operatedOrderVo.getOrdercat().getId());
			operatedOrderVo.setHasAddingKitchenItems(this.orderedItemDAO.hasAddingKitchenItems(operatedOrderVo.getOrdercat().getId()));
			operatedOrderVo.setHasKitchenItems(this.orderedItemDAO.hasKitchenItems(operatedOrderVo.getOrdercat().getId()));
		
			this.fileWriter.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	private void printOrderedItems(OperatedOrderVo operatedOrderVo, Recette recette) throws IOException{
		//this.enableUnderlineMode(this.receiptPrinterWriter);
		//this.fileWriter = new FileWriter(new File("mytextfile.txt"), true);
		this.fileWriter.write("Qu.  Item                   U.P.     Prix\n");
		//this.disableNoUnderlineMode(this.receiptPrinterWriter);
		for(int sortGroupId:this.orderedItemDAO.selectSortGroupByOrdercatId(operatedOrderVo.getOrdercat().getId())){
			for(OrderedItemVo orderedItemVo: this.orderedItemDAO.selectByOrdercatIdAndSortGroup(operatedOrderVo.getOrdercat().getId(), sortGroupId)){
				if(OrderedItemType.NORMAL.equals(orderedItemVo.getType()) || OrderedItemType.HOSTED.equals(orderedItemVo.getType())){
					String itemName = orderedItemVo.getItem().getName();
					this.fileWriter.write(String.format(RECEIPT_FORMAT_1, orderedItemVo.getQuantity(), itemName.length() > 18 ? itemName.substring(0, 15)+"..." : itemName, orderedItemVo.getItem().getUnitPrice(), orderedItemVo.getAmount()) + "\n");
				}
			}
		}
		this.printSingleLine();
		
		
		
		if(recette.getOffert() > 0){
			this.fileWriter.write(String.format(RECEIPT_FORMAT_2, "Offert:", (recette.getOffert()*-1)));
		}
		if(recette.getDiscountRate() > 0){
			this.fileWriter.write(String.format(RECEIPT_FORMAT_2, "Discount(-"+recette.getDiscountRate()+"%):", (recette.getDiscount()*-1)));
		}
		
		this.fileWriter.write(String.format(RECEIPT_FORMAT_2, "Total TVAC:", recette.getFinalTotal()));
		//this.fileWriter.close();
	}

	public void printReceiptToClient(OperatedOrderVo operatedOrderVo) {
		try {
			this.fileWriter = new FileWriter(new File(this.testPrintingOutputFile), true);
			SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy HH:MM");
			//this.setPrinterToNormalWidth(this.receiptPrinterWriter);
			//this.setLineSpacing(this.receiptPrinterWriter, this.receiptPrinterSpacing);
			Recette recette = this.recetteDAO.findByOrdercatId(operatedOrderVo.getOrdercat().getId());
			this.fileWriter.write("La Fontaine de Jade\n");
			this.fileWriter.write("Avenue de Tervuren, 5\n");
			this.fileWriter.write("1040 Etterbeek\n");
			this.printDoubleLine();
			this.fileWriter.write(operatedOrderVo.getOrdercat().getType().toString());
			
			if(OrderType.DINING_HALL.equals(operatedOrderVo.getOrdercat().getType())){
				this.fileWriter.write("     " + operatedOrderVo.getDiningTable().getLabel());
			}
			this.fileWriter.write("\n");
			this.printOrderedItems(operatedOrderVo, recette);
			this.fileWriter.write("\n");
			this.printDoubleLine();
			this.fileWriter.write("            Merci de votre visit");
			this.fileWriter.write("\n");
			
			//==============================================================================================
			this.fileWriter.write("Backup Ticket for Waiter\n");
			this.fileWriter.write("Order ID:" + operatedOrderVo.getOrdercat().getId());
			this.fileWriter.write("\n");
			this.fileWriter.write(operatedOrderVo.getOrdercat().getType() + "          " + dateFormat.format(operatedOrderVo.getOrdercat().getCreationTimestamp().getTime()));
			this.fileWriter.write("\n");
			this.printDoubleLine();
			this.printOrderedItems(operatedOrderVo, recette);
			
			this.fileWriter.write("\n");
			DecimalFormatSymbols otherSymbols = new DecimalFormatSymbols(Locale.US);
			otherSymbols.setDecimalSeparator('.');
			otherSymbols.setGroupingSeparator(','); 
			DecimalFormat df =new DecimalFormat("#.00", otherSymbols);
			
			this.printDoubleLine();
			this.fileWriter.write("%TVA          HTVA        TVA        TVAC\n");
			//this.disableNoUnderlineMode(this.receiptPrinterWriter);
			if(recette.getTva6() > 0){
				float htva = Float.valueOf(df.format(recette.getTva6()/1.06));
				float tva = Float.valueOf(df.format(recette.getTva6() - htva));
				this.fileWriter.write(String.format(RECEIPT_FORMAT_3, 6, htva, tva, recette.getTva6()));
				this.fileWriter.write("\n");
			}
			if(recette.getTva12() > 0){
				float htva = Float.valueOf(df.format(recette.getTva12()/1.12));
				float tva = Float.valueOf(df.format(recette.getTva12() - htva));
				this.fileWriter.write(String.format(RECEIPT_FORMAT_3, 12, htva, tva, recette.getTva12()));
				this.fileWriter.write("\n");
			}
			if(recette.getTva21() > 0){
				float htva = Float.valueOf(df.format(recette.getTva21()/1.21));
				float tva = Float.valueOf(df.format(recette.getTva21() - htva));
				this.fileWriter.write(String.format(RECEIPT_FORMAT_3, 21, htva, tva, recette.getTva21()));
				this.fileWriter.write("\n");
			}
			//this.receiptPrinterWriter.println();
			//this.receiptPrinterWriter.println();
//			this.cutPaper(this.receiptPrinterWriter);
//			this.receiptPrinterWriter.flush();
//			this.closeReceiptPrinterWriter();
			this.fileWriter.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

}
